#include "Texture.h"

namespace egg{

    Texture::Texture(PixelFormat::Format pf,uint32 w,uint32 h):
    mPixelFormat(pf){
        glGenTextures(1,&mID);
        RHILogError("Texture::construct");
        innerBuild(w,h,0);
    }

    Texture::Texture(PixelFormat::Format pf,uint32 w,uint32 h,const void* data):
    mPixelFormat(pf){
        glGenTextures(1,&mID);
        RHILogError("Texture::construct");
        innerBuild(w,h,data);
    }

    Texture::~Texture(){
        glDeleteTextures(1, &mID);
        RHILogError("Texture::destruct");
    }

    void Texture::resize(uint32 w,uint32 h){
        if(mWidth!=w||mHeight!=h){
            innerBuild(w,h,0);
        }
    }

    void Texture::writePixels(const void* data){
        glBindTexture(GL_TEXTURE_2D,mID);
        glTexSubImage2D(
            GL_TEXTURE_2D, 0, 0, 0, 
            mWidth, mHeight, 
            mPixelFormat.mRHIFormat, 
            mPixelFormat.mRHIType, 
            data);
        glBindTexture(GL_TEXTURE_2D,0);
        RHILogError("Texture::updatePixels");
    }

    void Texture::readPixels(void* dest){
        glBindTexture(GL_TEXTURE_2D,mID);
        glGetTexImage(GL_TEXTURE_2D, 0, mPixelFormat.mRHIFormat, mPixelFormat.mRHIType,dest);
        glBindTexture(GL_TEXTURE_2D,0);
        RHILogError("Texture::updatePixels");
    }

    void Texture::innerBuild(uint32 w,uint32 h,const void* data){
        mWidth=w;
        mHeight=h;
        if(data)
            mIsImage=true;
        else
            mIsImage=false;
        glBindTexture(GL_TEXTURE_2D,mID);
        if(mIsImage){
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            gluBuild2DMipmaps(
                GL_TEXTURE_2D,
                mPixelFormat.mRHIInnerFormat,
                mWidth,mHeight,
                mPixelFormat.mRHIFormat,
                mPixelFormat.mRHIType,
                data);
        }else{
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            if(mPixelFormat.mFormat==PixelFormat::D24S8){
                glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
            }
            glTexImage2D(
                GL_TEXTURE_2D,0,
                mPixelFormat.mRHIInnerFormat,
                mWidth,mHeight,0,
                mPixelFormat.mRHIFormat,
                mPixelFormat.mRHIType,
                0);
        }
        glBindTexture(GL_TEXTURE_2D,0);
        RHILogError("Texture::innerBuild");
    }

}